// libmusico.h

#pragma once

using namespace System;
using namespace System::Collections::Generic;

namespace libmusico {

	/// <summary>
	/// <c> Message </c> is the base class defining a MIDI message 
	/// </summary>
	public ref class Message: public Object
	{
	internal:
		unsigned int channel;				/// <value> The channel of the MIDI message </value>
		unsigned char status;				/// <value> The status of the message (i.e. Note ON, OFF or PC) </value>
		unsigned char note;					/// <value> The note played (or message sent) </value>
		unsigned char velocity;				/// <value> The velocity of the note (i.e. volume for a note) </value>

	public:
		/// <summary> Constructor </summary>
		Message();							
		/// <summary> Constructor with initial messages </summary>
		/// <param name="c"> The channel used to send the message </param>
		/// <param name="s"> The status of the message </param>
		/// <param name="n"> The note of the message </param>
		/// <param name="v"> The velocity of the message </param>
		Message(int c, int s, int n, int v);		

		/// <summary> Returns the MIDI channel </summary>
		/// <returns> the MIDI channel </returns>
		unsigned int getChannel();

		/// <summary> Returns the Status </summary>
		/// <returns> the Status </returns>
		unsigned char getStatus();

		/// <summary> Returns the MIDI byte 1 </summary>
		/// <returns> the MIDI byte 1 </returns>
		unsigned char getMidiOne();

		/// <summary> Returns the MIDI byte 2 </summary>
		/// <returns> the MIDI byte 2 </returns>
		unsigned char getMidiTwo();

		/// <summary> Returns the MIDI message
		/// <returns> A long integer that can be read by midiOutShortMessage() </returns>
		/// </summary>
		unsigned long int getMIDI();		
		/// <summary> Turns a message OFF </summary>
		void turnOFF();						
	};

	public ref class Command: public Object
	{
	private:
		Dictionary<String^, Message^>^ messages;		// list of commands

	public:
		Command();								// Constructor

		void addMessage(String^, Message^);		// Add a message to the command
		void delMessage(String^);				// Delete a message to the command
		void getMessage(String^, Message ^%);	// Access a single message in the command
		void stop(Int16, String^);				// Stop a message sent to a MIDI out

		virtual String^ print();				// Print a readable version of the command
		virtual void send(Int16);				// Send the command to the device
		virtual void send(Int16, Int32);		// Send the command to the device, with a given duration

		void writeTo(String^, String^);			// Write the command to a file in XML format
		String^ loadFrom(String^);				// Load a command from an XML file
	};
}